package com.haohan.cloud.scm.common.tools.annotation;

import cn.hutool.core.util.StrUtil;
import com.fasterxml.jackson.annotation.JsonFilter;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter;
import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;

import java.util.Collections;
import java.util.HashSet;

/**
 * @author dy
 * @date 2019/5/17
 */
public class ScmJsonSerializer {

    static final String DYNC_INCLUDE = "DYNC_INCLUDE";
    static final String DYNC_FILTER = "DYNC_FILTER";
    ObjectMapper mapper = new ObjectMapper();

    @JsonFilter(DYNC_FILTER)
    interface DynamicFilter {
    }

    @JsonFilter(DYNC_INCLUDE)
    interface DynamicInclude {
    }

    /**
     * @param clazz   需要设置规则的Class
     * @param include 转换时包含哪些字段
     * @param filter  转换时过滤哪些字段
     * @param add     在filter 的 基础上 添加需要包含的字段
     */
    public void filter(Class<?> clazz, String include, String filter, String add) {
        if (clazz == null) {
            return;
        }
        SimpleBeanPropertyFilter sbpFilter = null;
        if (StrUtil.isNotEmpty(include)) {
            sbpFilter = SimpleBeanPropertyFilter.filterOutAllExcept(include.split(","));
        } else if (StrUtil.isNotEmpty(filter)) {
            String[] filterArray = filter.split(",");
            HashSet<String> properties = new HashSet(filterArray.length);
            Collections.addAll(properties, filterArray);
            if (StrUtil.isNotEmpty(add)) {
                String[] addArray = add.split(",");
                for (int i = 0; i < addArray.length; i++) {
                    properties.remove(addArray[i]);
                }
            }
            sbpFilter = SimpleBeanPropertyFilter.serializeAllExcept(properties);
        }
        if (null != sbpFilter) {
            mapper.setFilterProvider(new SimpleFilterProvider().addFilter(DYNC_FILTER, sbpFilter));
            mapper.addMixIn(clazz, DynamicFilter.class);
        }
    }

    public String toJson(Object object) throws JsonProcessingException {
        return mapper.writeValueAsString(object);
    }
}
